package com.farshine.baokan.box;

import java.io.UnsupportedEncodingException;

public class BoxControl {

    public interface BoxStatMessage {
        void OnBoxStatChange(int addr, boolean lockIsOpen, boolean btn1IsClick, boolean btn2IsClick, String cardNo);
    }

    private final SendCommand sendCommand;
    private final MakeCommand makeCommand;

    private BoxStatMessage onMessage;

    private boolean bOpen = false;
    private int minAddr = 1;
    private int maxAddr = 0;

    /**
     * 初始化控制类
     * @param ip 转换器IP
     * @param port 转换器端口
     * @param minAddr 联机箱头最小地址
     * @param maxAddr 联机箱头最大地址
     */
    public BoxControl(String ip, int port, int minAddr, int maxAddr, BoxStatMessage onMessage) {
        sendCommand = new SendCommand();
        makeCommand = new MakeCommand();
        this.onMessage = onMessage;

        this.minAddr = minAddr; this.maxAddr = maxAddr;
        start(ip, port);
    }

    public void setOnMessage(BoxStatMessage onMessage) {
        this.onMessage = onMessage;
    }

    /**
     * 开始监控箱头
     * @param ip 转换器IP
     * @param port 转换器端口
     * @return 是否成功
     */
    public boolean start(String ip, int port) {
        if (bOpen) return true;
        bOpen = sendCommand.open(ip, port);
        if (bOpen && minAddr>0 && maxAddr>=minAddr) {
            //循环检测报刊箱
            threadCheckBox.start();
        }
        return bOpen;
    }

    private Thread threadCheckBox = new Thread(new Runnable () {
        public void run() {
            byte[] buf = new byte[0];
            while (bOpen) {
                for (int addr=minAddr; addr<=maxAddr && bOpen; addr++) {
                    try {
                        //生成查询命令
                        byte[] command = makeCommand.make(CommandTyep.Chaxun_zhuangtai, addr, buf);
                        byte[] data = null;
                        //同步
                        synchronized (sendCommand) {
                            //发送
                            boolean bsend = sendCommand.send(command);
                            if (bsend) {
                                //读取反馈数据
                                data = sendCommand.read();
                            }
                        }
                        if (data != null && data.length > 12) {
                            //解析
                            MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                            if (boxCommand != null && boxCommand.command.equals(CommandTyep.Chaxun_zhuangtai)) {
                            /* 1字节：门锁状态，0x40：关闭，0x41：打开
                               2字节：按键状态，0x40：没有按键事件，0x41：有第一个按键事件，
                                                0x42：有第二个按键事件。0x43：第一第二按键都有事件。
                               3～：为卡号数据。 */
                                boolean lockIsOpen = boxCommand.data[0] == 0x41;
                                boolean btn1IsClick = boxCommand.data[1] == 0x41 || boxCommand.data[1] == 0x43;
                                boolean btn2IsClick = boxCommand.data[1] == 0x42 || boxCommand.data[1] == 0x43;
                                String cardNo = "";
                                if (boxCommand.data.length > 2) {
                                    byte[] cardbuf = new byte[(boxCommand.data.length - 2) / 2];
                                    for (int i = 2; i < boxCommand.data.length; i += 2) {
                                        cardbuf[i / 2] = (byte) ((boxCommand.data[i] & 0x0F) | ((boxCommand.data[i + 1] & 0x0F) << 4));
                                    }
                                    cardNo = new String(cardbuf);
                                }
                                System.out.println("检查状态："+addr+", lockIsOpen="+lockIsOpen+", btn1IsClick="+btn1IsClick+", btn2IsClick="+btn2IsClick);
                                if (onMessage!=null) {
                                    onMessage.OnBoxStatChange(addr, lockIsOpen, btn1IsClick, btn2IsClick, cardNo);
                                }
                            }
                        }
                        //暂停
                        Thread.sleep(5);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    });

    /**
     * 关闭箱头控制
     */
    public void stop() {
        if (bOpen) {
            bOpen = false;
            try {
                threadCheckBox.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sendCommand.close();
        }
    }


    /**
     * 控制指示灯
     * @param addr 地址
     * @param index 指示灯序号，1,2,3,4
     * @param state 指示灯状态，0x40：灭，0x41：亮：0x42：闪烁
     * @return 是否成功
     */
    public boolean setBoxLight(int addr, int index, int state) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[2];
                buf[0] = (byte)(0x40 + index);
                buf[1] = (byte)(state);
                byte[] command = makeCommand.make(CommandTyep.Zhishideng, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Zhishideng)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 控制数码管
     * @param addr 地址
     * @param index 1，第一块数码管；2，第二块数码管
     * @param number 应显示的数字
     * @param state 状态，
     * 0x40：黑色（即为关闭数码管）
     * 0x41：绿色
     * 0x42：红色
     * 0x43：橙色
     * 0x44：绿-黑 闪烁
     * 0x45：红-黑 闪烁
     * 0x46：橙-黑 闪烁
     * 0x47：红-绿 闪烁
     * 0x48：橙-绿 闪烁
     * @return 是否成功
     */
    public boolean setBoxNumber(int addr, int index, int number, int state) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[5];
                buf[0] = (byte)(0x40 + (number & 0x0F));
                buf[1] = (byte)(0x40 + ((number>>4) & 0x0F));
                buf[2] = (byte)(0x40 + ((number>>8) & 0x0F));
                buf[3] = (byte)(0x40 + index);
                buf[4] = (byte)(state);
                byte[] command = makeCommand.make(CommandTyep.Shumaguan, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Shumaguan)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 控制门锁打开
     * @param addr 地址
     * @return 是否成功
     */
    public boolean setBoxLock(int addr) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[0];
                byte[] command = makeCommand.make(CommandTyep.Mensuo, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Mensuo)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 屏幕显示文本
     * @param addr 地址
     * @param text 屏幕显示文本
     * @return 是否成功
     */
    public boolean setBoxText(int addr, String text) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] textbuf = text.getBytes("GBK");
                byte[] buf = new byte[textbuf.length * 2 + 1];
                buf[0] = 0x41; //第一块显示屏
                for (int i=0;i<textbuf.length;i++) {
                    buf[i*2 + 1] = (byte)((textbuf[i] & 0x0F) + 0x40);
                    buf[i*2 + 2] = (byte)(((textbuf[i]>>4) & 0x0F) + 0x40);
                }
                byte[] command = makeCommand.make(CommandTyep.Pingmu_xianshiWenben, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Pingmu_xianshiWenben)) {
                        bRet = true;
                    }
                    Thread.sleep(1000);
                }

                //第二块显示屏
                buf[0] = 0x42;
                command = makeCommand.make(CommandTyep.Pingmu_xianshiWenben, addr, buf);
                data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Pingmu_xianshiWenben)) {
                        bRet = true;
                    }
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 系统软启动
     * @param addr 地址
     * @return 是否成功
     */
    public boolean setBoxReboot(int addr) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[0];
                byte[] command = makeCommand.make(CommandTyep.System_reboot, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.System_reboot)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 蜂鸣器控制命令
     * @param addr 地址
     * @param state 0x40：停止，
     *              0x41：提示音，只响一声，然后自动停止
     *              0x42：提示音，连续响3声，然后自动停止
     *              0x43：错误提示音，连响3声，然后连续响，收到停止命令才停止
     *              其他：暂无定义
     * @return 是否成功
     */
    public boolean setBoxVoice(int addr, int state) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[1];
                buf[0] = (byte)(state);
                byte[] command = makeCommand.make(CommandTyep.Fengmingqi, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Fengmingqi)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }

    /**
     * 屏幕控制命令
     * @param addr 地址
     * @param state 0x40：屏幕正常显示，
     *              0x41：屏幕熄灭
     *              其他：暂无定义
     * @return 是否成功
     */
    public boolean setBoxLcdShow(int addr, int state) {
        boolean bRet = false;
        if (bOpen) {
            //生成查询命令
            try {
                byte[] buf = new byte[1];
                buf[0] = (byte)(state);
                byte[] command = makeCommand.make(CommandTyep.Pingmu_kongzhi, addr, buf);
                byte[] data = null;
                //同步
                synchronized (sendCommand) {
                    //发送
                    boolean bsend = sendCommand.send(command);
                    if (bsend) {
                        //读取反馈数据
                        data = sendCommand.read();
                    }
                }
                if (data != null && data.length >= 12) {
                    //解析
                    MakeCommand.BoxCommand boxCommand = makeCommand.parse(data);
                    if (boxCommand != null && boxCommand.command.equals(CommandTyep.Pingmu_kongzhi)) {
                        bRet = true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return bRet;
    }
}
